package com.lry.config;

import com.alibaba.ttl.threadpool.TtlExecutors;
import com.lry.config.condition.EaEnableCondition;
import com.lry.handler.DefaultExceptionHandler;
import com.lry.handler.ExceptionHandler;
import com.lry.properties.EaProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@Conditional(EaEnableCondition.class)
@EnableConfigurationProperties(EaProperties.class)
@Slf4j
public class EaConfig {


    @Bean
    public ExceptionHandler exceptionHandler(EaProperties eaProperties,
                                             ApplicationEventPublisher applicationEventPublisher) {
        log.debug("创建异常处理器");
        ExceptionHandler exceptionHandler = new DefaultExceptionHandler(eaProperties, applicationEventPublisher);
        return exceptionHandler;
    }



    @Bean
    public Executor eaTaskExecutor() {

        // transmittable代理，使得在新建线程或者线程池执行任务的时候，能够共享ThreadLocal变量
        return TtlExecutors.getTtlExecutor(eaThreadPoolTaskExecutor());
    }


    @Primary
    @Bean
    public ThreadPoolTaskExecutor eaThreadPoolTaskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(20);
        // 设置最大线程数
        executor.setMaxPoolSize(20);
        // 设置队列容量
//        executor.setQueueCapacity(2);
        // 设置线程活跃时间（秒）
        executor.setKeepAliveSeconds(300);
        // 设置默认线程名称
        executor.setThreadNamePrefix("taskExecutor-");
        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.initialize();
        return executor;
    }

}
